#include "sys.h"
#include "usart.h"
#include "bsp_led.h"

#define TX_BUFFER_SIZE (512)
#define RX_BUFFER_SIZE (512)

// 环形缓冲区结构
static uint8_t tx_buffer[TX_BUFFER_SIZE];
static volatile uint16_t tx_head = 0;   // 缓冲区写入索引
static volatile uint16_t tx_tail = 0;   // 缓冲区读取索引
static volatile uint8_t tx_busy = 0;    // 发送状态标记
uint8_t rx_buffer[RX_BUFFER_SIZE];
static volatile uint16_t rx_head = 0;
static volatile uint16_t rx_tail = 0;

void uart_init(uint32_t baudrate)
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStruct;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

	USART_DeInit(USART1);

	//串口1对应引脚复用映射
	GPIO_PinAFConfig(BSP_USART_TX_PORT, BSP_USART_TX_AF_PIN, BSP_USART_AF);
	GPIO_PinAFConfig(BSP_USART_RX_PORT, BSP_USART_RX_AF_PIN, BSP_USART_AF);
	
	//USART1端口配置
	GPIO_InitStructure.GPIO_Pin = BSP_USART_TX_PIN | BSP_USART_RX_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//USART1 初始化设置
	USART_InitStructure.USART_BaudRate = baudrate;//波特率设置
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(BSP_USART, &USART_InitStructure);

	USART_ClearFlag(BSP_USART, USART_FLAG_RXNE);//初始配置时清除接受置位

	USART_ITConfig(BSP_USART, USART_IT_RXNE, ENABLE);

	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);

	USART_Cmd(BSP_USART, ENABLE);
}

//告诉编译器禁用“半主机模式”
#pragma import(__use_no_semihosting)

//为C标准库提供文件操作的基础结构
struct __FILE
{
	int handle;
};

//为C标准库提供文件操作的基础结构
FILE __stdout;

//重定义退出函数，避免标准库调用半主机模式的退出函数
void _sys_exit(int x)
{
	x = x;
}

static void tx_buffer_push(uint8_t data)
{
	uint16_t next_head = (tx_head + 1) % TX_BUFFER_SIZE;
	if (next_head != tx_tail) {
		tx_buffer[tx_head] = data;
		tx_head = next_head;

		if (!tx_busy) {
			tx_busy = 1;
			USART_ITConfig(BSP_USART, USART_IT_TXE, ENABLE);
		}
	}
}

//重定向字符输出函数
int fputc(int ch, FILE *f)
{
	if (ch == '\n') {
		tx_buffer_push('\r');
	}
	tx_buffer_push((uint8_t)ch);
	return ch;
}

void usart_safe_sendstring(uint8_t *str)
{
	while (*str) {
		tx_buffer_push(*str++);
	}
}

// 从接收缓冲区读取一个字节（返回1表示成功，0表示无数据）
uint8_t rx_buffer_pop(uint8_t *data)
{
    if (rx_head != rx_tail) {
        *data = rx_buffer[rx_tail];
        rx_tail = (rx_tail + 1) % RX_BUFFER_SIZE;
        return 1;
    }
    return 0;
}

void USART1_IRQHandler(void)
{
	if (USART_GetITStatus(BSP_USART, USART_IT_TXE)) {
		if (tx_head != tx_tail) {
			USART_SendData(BSP_USART, tx_buffer[tx_tail]);
			tx_tail = (tx_tail + 1) % TX_BUFFER_SIZE;
		} else {
			tx_busy = 0;
			USART_ITConfig(BSP_USART, USART_IT_TXE, DISABLE);
		}
		USART_ClearITPendingBit(BSP_USART, USART_IT_TXE);
	}

	if (USART_GetITStatus(BSP_USART, USART_IT_RXNE)) {
		uint8_t recv_data = USART_ReceiveData(BSP_USART);
		uint16_t next_rx_head = (rx_head + 1) % RX_BUFFER_SIZE;
		if (next_rx_head != rx_tail) {
			rx_buffer[rx_head] = recv_data;
			rx_head = next_rx_head;
		}
		USART_ClearITPendingBit(BSP_USART, USART_IT_RXNE);
	}
}
